<template>
  <span>{{ displayNumber }}</span>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";

const props = defineProps({
  targetNumber: {
    type: Number,
    required: true
  },
  duration: {
    type: Number,
    default: 500
  }
});

const displayNumber = ref(0);
let startTime: number | null = null;

function animate(timestamp: number) {
  if (!startTime) startTime = timestamp;
  const progress = timestamp - startTime;
  if (progress < props.duration) {
    displayNumber.value = Math.floor((props.targetNumber * progress) / props.duration);
    requestAnimationFrame(animate);
  } else {
    displayNumber.value = props.targetNumber;
  }
}

onMounted(() => {
  requestAnimationFrame(animate);
});

watch(
  () => props.targetNumber,
  () => {
    displayNumber.value = 0;
    startTime = null;
    requestAnimationFrame(animate);
  }
);
</script>
